package com.hspedu.seckill.controller;

import com.hspedu.seckill.entity.User;
import com.hspedu.seckill.model.constant.RedisCacheConstant;
import com.hspedu.seckill.model.vo.GoodsVo;
import com.hspedu.seckill.service.GoodsService;
import com.hspedu.seckill.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author: xujiabing
 * @date: 2024-10-03 16:21
 * @description 商品列表控制层
 */
@Controller
@RequestMapping("/goods")
public class GoodsController {
    @Autowired
    private UserService userService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private RedisTemplate redisTemplate;
    //手动渲染
    @Resource
    private ThymeleafViewResolver thymeleafViewResolver;

    /**
     * 跳转到商品列表页 v3.0-参数解析器+redis页面缓存优化
     *
     * @param model model域
     * @param user  由自定义参数解析器，解析后封装到user
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/toList", produces = "text/html;charset=utf-8")
    public String toList(HttpServletRequest request, HttpServletResponse response,
                         Model model, User user) {

        if (Objects.isNull(user)) {
            //没有登录，转到登录页
            return "login";
        }
        //先去redis中查询页面-如果有直接返回
        ValueOperations opsForValue = redisTemplate.opsForValue();
        String goodsListIndex = (String) opsForValue.get(RedisCacheConstant.GOODS_LIST);
        if (StringUtils.isNotBlank(goodsListIndex)) {
            return goodsListIndex;
        }
        //将user信息放入到model中，供下一个页面取出
        model.addAttribute("user", user);
        //将商品列表西信息放入到model中
        model.addAttribute("goodsList", goodsService.findGoodsVo());

        //从redis中没有获取到页面缓存,手动渲染，并存入到redis
        WebContext webContext =
                new WebContext(request, response, request.getServletContext()
                        , request.getLocale(), model.asMap());
        //渲染好的页面
        String html = thymeleafViewResolver.
                getTemplateEngine().process(RedisCacheConstant.GOODS_LIST, webContext);

        if (StringUtils.isNotBlank(html)) {
            //每60s 更新一次redis 页面缓存, 即60s 后, 该页面缓存失效, Redis 会清除该页面缓存
            opsForValue.set(RedisCacheConstant.GOODS_LIST
                    , html, RedisCacheConstant.CACHE_TIME, TimeUnit.SECONDS);
        }
        return html;
    }

    /**
     * 进入商品秒杀详情界面,根据商品id-v2.0 增加redis缓存页面机制
     *
     * @param model
     * @param user
     * @param goodsId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/toDetail/{goodsId}", produces = "text/html;charset=utf-8")
    public String toDetail(Model model, User user,
                           HttpServletRequest request, HttpServletResponse response,
                           @PathVariable("goodsId") Long goodsId) {
        if (Objects.isNull(user)) {
            //没有登录，转到登录页
            return "login";
        }
        //1.先去redis中获取商品详情数据
        ValueOperations opsForValue = redisTemplate.opsForValue();
        String goodsDetailIndex = (String) opsForValue
                .get(RedisCacheConstant.GOODS_DETAIL + ":" + goodsId);

        if (StringUtils.isNotBlank(goodsDetailIndex)) {
            return goodsDetailIndex;
        }

        //将user信息放入到model中，供下一个页面取出
        model.addAttribute("user", user);
        //获取秒杀商品信息
        GoodsVo goodsVo = goodsService.findGoodsVoByGoodsId(goodsId);
        //放入到model中
        model.addAttribute("goods", goodsVo);

        //返回商品详情时，同时返回秒杀状态[未开始，进行中，结束]，和秒杀剩余时间
        //1.变量 seckillStatus 秒杀状态[0:未开始,1:进行中,2:已结束]
        //2.变量 remainSeconds 秒杀剩余秒数[>0:表示还有多久开始秒杀, =0:进行中, <0:已经结束]

        //获取当前商品的秒杀开始时间和结束时间
        Date startDate = goodsVo.getStartDate();
        Date endDate = goodsVo.getEndDate();
        //声明变量
        int secKillStatus = 0;
        int remainSeconds = 0;
        //当前时间
        Date nowDate = new Date();
        if (nowDate.before(startDate)) {//未开始
            //计算并返回剩余时间 getTime() 返回毫秒数
            remainSeconds = (int) ((startDate.getTime() - nowDate.getTime()) / 1000);
            secKillStatus = 0;
        } else if (nowDate.after(endDate)) {//已结束
            secKillStatus = 2;
            remainSeconds = -1;
        } else {//进行中
            secKillStatus = 1;
            remainSeconds = 0;
        }
        //将秒杀状态，和剩余时间放入model中
        model.addAttribute("secKillStatus", secKillStatus);
        model.addAttribute("remainSeconds", remainSeconds);

        //将商品详情页，放入redis中
        //从redis中没有获取到页面缓存,手动渲染，并存入到redis
        WebContext webContext =
                new WebContext(request, response, request.getServletContext()
                        , request.getLocale(), model.asMap());
        //渲染好的页面
        String html = thymeleafViewResolver.
                getTemplateEngine().process(RedisCacheConstant.GOODS_DETAIL, webContext);

        if (StringUtils.isNotBlank(html)) {
            //每60s 更新一次redis 页面缓存, 即60s 后, 该页面缓存失效, Redis 会清除该页面缓存
            opsForValue.set(RedisCacheConstant.GOODS_DETAIL + ":" + goodsId
                    , html, RedisCacheConstant.CACHE_TIME, TimeUnit.SECONDS);
        }

        return html;
    }

//    /**
//     * 跳转到商品列表页 v2.0-参数解析器+从db获取数据
//     *
//     * @param model model域
//     * @param user  由自定义参数解析器，解析后封装到user
//     * @return
//     */
//    @RequestMapping("/toList")
//    public String toList(Model model, User user) {
//
//        if (Objects.isNull(user)) {
//            //没有登录，转到登录页
//            return "login";
//        }
//        //将user信息放入到model中，供下一个页面取出
//        model.addAttribute("user", user);
//        //将商品列表西信息放入到model中
//        model.addAttribute("goodsList", goodsService.findGoodsVo());
//
//        return "goodsList";
//    }

//    /**
//     * 进入商品秒杀详情界面,根据商品id-v1.0 每次到数据库查询
//     *
//     * @param model
//     * @param user
//     * @param goodsId
//     * @return
//     */
//    @RequestMapping("/toDetail/{goodsId}")
//    public String toDetail(Model model, User user,
//                           @PathVariable("goodsId") Long goodsId) {
//        if (Objects.isNull(user)) {
//            //没有登录，转到登录页
//            return "login";
//        }
//        //将user信息放入到model中，供下一个页面取出
//        model.addAttribute("user", user);
//        //获取秒杀商品信息
//        GoodsVo goodsVo = goodsService.findGoodsVoByGoodsId(goodsId);
//        //放入到model中
//        model.addAttribute("goods", goodsVo);
//
//        //返回商品详情时，同时返回秒杀状态[未开始，进行中，结束]，和秒杀剩余时间
//        //1.变量 seckillStatus 秒杀状态[0:未开始,1:进行中,2:已结束]
//        //2.变量 remainSeconds 秒杀剩余秒数[>0:表示还有多久开始秒杀, =0:进行中, <0:已经结束]
//
//        //获取当前商品的秒杀开始时间和结束时间
//        Date startDate = goodsVo.getStartDate();
//        Date endDate = goodsVo.getEndDate();
//        //声明变量
//        int secKillStatus = 0;
//        int remainSeconds = 0;
//        //当前时间
//        Date nowDate = new Date();
//        if (nowDate.before(startDate)) {//未开始
//            //计算并返回剩余时间 getTime() 返回毫秒数
//            remainSeconds = (int) ((startDate.getTime() - nowDate.getTime()) / 1000);
//            secKillStatus = 0;
//        } else if (nowDate.after(endDate)) {//已结束
//            secKillStatus = 2;
//            remainSeconds = -1;
//        } else {//进行中
//            secKillStatus = 1;
//            remainSeconds = 0;
//        }
//        //将秒杀状态，和剩余时间放入model中
//        model.addAttribute("secKillStatus", secKillStatus);
//        model.addAttribute("remainSeconds", remainSeconds);
//        return "goodsDetail";
//    }

//    /**
//     * 跳转到商品列表页 v1.0-在方法内校验+db查询
//     * @param request request
//     * @param response response
//     * @param model model域存放页面需要的数据
//     * @param ticket 登录成功生成唯一值
//     * @return
//     */
//    @RequestMapping("/toList")
//    public String toList(HttpServletRequest request,
//                         HttpServletResponse response,
//                         Model model,
//                         @CookieValue("userTicket") String ticket) {
//        //校验cookie是否生成
//        if (StringUtils.isBlank(ticket)) {
//            //没有登录，转到登录页
//            return "login";
//        }
//        //验证 ticket 是否有效
//        //User user = (User)session.getAttribute(ticket);
//
//        //v2.0 改成从redis获取user信息
//        User user = userService.getUserByCookie(ticket, request, response);
//
//        if (Objects.isNull(user)) {
//            //没有登录，转到登录页
//            return "login";
//        }
//        model.addAttribute("user",user);
//
//        return "goodsList";
//    }

}
